home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <ctype.h>
- #include "../misc/misc.h"
- #include "askrunlevel.h"
- #include "internal.h"
- #include "../userconf/userconf.h"
- #include "../netconf/netconf.h"
- #include "../paths.h"
- #include "askrunlevel.m"
-
- static HELP_FILE help_default (HELP_ASKRUN,"default");
- static HELP_FILE help_define (HELP_ASKRUN,"define");
-
-
- // Some keys for /etc/conf.linuxconf
- static const char ASKRUNLEVEL[]="askrunlevel";
- static const char TIMEOUT[]="timeout";
- static const char DEFMODE[]="defmode";
- static const char K_RUNLEVEL[]="runlevel";
-
- #define NB_RUNLEVEL 6
- /*
- Write the configuration parameter into /etc/askrunlevel.conf
- */
- static int askrunlevel_saveparm(ASK_PARM &parm)
- {
- linuxconf_replace (ASKRUNLEVEL,TIMEOUT,parm.timeout);
- linuxconf_replace (ASKRUNLEVEL,DEFMODE,parm.defmode);
- return linuxconf_save();
- }
- /*
- Write the configuration parameter into /etc/askrunlevel.conf
- */
- void askrunlevel_readparm(ASK_PARM &parm)
- {
- parm.timeout = linuxconf_getvalnum(ASKRUNLEVEL,TIMEOUT,0);
- parm.defmode = linuxconf_getvalnum(ASKRUNLEVEL,DEFMODE,4);
- /* #Specification: askrunlevel / configuration file
- askrunlevel stores its default operation mode into
- /etc/conf.linuxconf. This file is optionnal. The
- default setup is:
-
- runlevel 5, netlevel 0 -> text mode, no networking
- No timeout (askrunlevel will wait forever)
- */
- }
-
- /*
- parse one line of /etc/conf.linuxconf
- */
- PRIVATE void RUNLEVELS::parse (const char *str, RUNLEVEL *ptrun)
- {
- /* #Specification: askrunlevel / runlevel definition / /etc/conf.linuxconf
- The definitions of the different operation mode are
- stored in /etc/conf.linuxconf with the following format
-
- #
- askrunlevel.runlevel init net graphic_mode title ...
- Where,
-
- init (runlevel for /sbin/init) is one of
- 1,2,3,4,5,6,S
-
- net is 0 1 or 2 for no network, client network and
- server respectivly
-
- graphic is 0 1 or 2 for text mode, graphic mode (workstation)
- and X terminal respectivly.
- #
-
- */
- str = str_skip(str);
- ptrun->init_runlevel = *str++;
- str = str_skip(str);
- ptrun->netconf_runlevel = atoi(str++);
- str = str_skip(str);
- ptrun->graphic_level = atoi(str++);
- ptrun->title.setfrom (str_skip(str));
- }
-
- /*
- Definition of the different runlevels available
- */
- PUBLIC RUNLEVELS::RUNLEVELS(
- int graphic_ok,
- int net_ok)
- {
- static struct {
- const char *mode;
- const char *title;
- }default_tbrun[]={
- {"4 2 1",MSG_U(M_GR_NET,"Graphic & Network")},
- {"4 0 1",MSG_U(M_GRONLY,"Graphic only")},
- {"2 1 2",MSG_U(M_XTERMINAL,"X terminal")},
- {"5 2 0",MSG_U(M_TX_NET,"Text mode & Network")},
- {"3 0 0",MSG_U(M_TXONLY,"Text mode only")},
- {"S 0 0",MSG_U(M_MAINTENANCE,"Maintenance mode")},
- };
- SSTRINGS lst;
- /* #Specification: askrunlevel / operation mode / definition
- The definition of the six different operation
- mode are defined in /etc/conf.linuxconf
- */
- linuxconf_getall (ASKRUNLEVEL,K_RUNLEVEL,lst,0);
- RUNLEVEL *ptrun = tbrun;
- for (int i=0; i<NB_RUNLEVEL; i++, ptrun++){
- if (i<lst.getnb()){
- parse (lst.getitem(i)->get(),ptrun);
- }else{
- char buf[100];
- sprintf (buf,"%s %s",default_tbrun[i].mode,default_tbrun[i].title);
- parse (buf,ptrun);
- }
- ptrun->graphic_err = ptrun->graphic_level > 0
- && !graphic_ok;
- ptrun->net_err = ptrun->netconf_runlevel > 0 && !net_ok;
- char buf[80];
- ptrun->title.copy(buf);
- if (ptrun->graphic_err || ptrun->net_err){
- strcat (buf," ");
- strcat (buf,MSG_U(M_NOTCONF,"(Not configured)"));
- }
- tbmenu[i].setfrom (buf);
- }
- }
-
- PUBLIC RUNLEVELS::~RUNLEVELS()
- {
- }
-
- PUBLIC void RUNLEVELS::save()
- {
- linuxconf_removeall (ASKRUNLEVEL,K_RUNLEVEL);
- RUNLEVEL *ptrun = tbrun;
- for (int i=0; i<NB_RUNLEVEL; i++, ptrun++){
- char buf[80];
- sprintf (buf,"%c %d %d %s"
- ,ptrun->init_runlevel
- ,ptrun->netconf_runlevel
- ,ptrun->graphic_level
- ,ptrun->title.get());
- linuxconf_add (ASKRUNLEVEL,K_RUNLEVEL,buf);
- }
- linuxconf_save();
- }
-
- PUBLIC void RUNLEVELS::setmenu (
- const char *menuopt[])
- {
- int ii=1;
- for (unsigned i=0; i<sizeof(tbrun)/sizeof(tbrun[0]); i++, ii+=2){
- menuopt[ii] = tbmenu[i].get();
- }
- }
-
- /*
- Record the selected runlevels in the different files used later.
- */
- PUBLIC void RUNLEVELS::setlevel(int choice)
- {
- /* #Specification: askrunlevel / talking to init / compatibitily
- Most init expect to receive their new runlevel in
- /etc/initrunlvl. Some do expect it in /var/run/initrunlvl.
- I feel the later make more sens. Anyway, askrunlevel write
- at both places.
-
- The askrunlevel utility was originally called by init
- directly. It has been found that askrunlevel could be called
- at the end of /etc/rc.d/rc.S (or whatever is on your system)
- without any special support from init. The current askrunlevel
- is playing is calling init to select the proper runlevel.
- */
- static char *tb[]={
- VAR_RUN_INITRUNLEVEL,
- ETC_INITRUNLEVEL
- };
- char levelstr[2];
- levelstr[0] = tbrun[choice].init_runlevel;
- levelstr[1] = '\0';
- for (int i=0; i<2; i++){
- FILE *fout = xconf_fopen (tb[i],"w");
- if (fout != NULL){
- fprintf (fout,"%s\n",levelstr);
- fclose (fout);
- }
- }
- netconf_setnetlevel (tbrun[choice].netconf_runlevel);
- netconf_system_if ("telinit",levelstr);
- }
-
-
- /*
- Let the user select the default runlevel for for next run
- */
- PUBLIC void RUNLEVELS::config()
- {
- if (perm_rootaccess(MSG_U(P_BOOTMODE,"change the boot mode"))){
- ASK_PARM parm;
- askrunlevel_readparm (parm);
- DIALOG dia;
- dia.newf_title ("",MSG_U(T_DEFOPER,"Default operation mode"));
- char choice = parm.defmode;
- for (int i=0; i<5; i++){
- dia.newf_radio ("",choice,i,tbmenu[i].get());
- }
- dia.newf_title ("","");
- dia.newf_num (MSG_U(F_DELAY,"Delay to activate"),parm.timeout);
- if (dia.edit (MSG_U(T_BOOTCMODE,"Boot mode configuration")
- ,MSG_U(I_BOOTCMODE,"Select the default operation mode\n"
- "and a timeout. A timeout of 0 means\n"
- "to wait forever.\n")
- ,help_default.getpath()
- ,0)==MENU_ACCEPT){
- parm.defmode = choice;
- askrunlevel_saveparm (parm);
- RUNLEVEL *ptrun = tbrun + choice;
- if (ptrun->graphic_err || ptrun->net_err){
- xconf_notice(MSG_U(N_NOTCONF,"This runlevel is not yet"
- " configured"));
- }
- }
- }
- }
-
- /*
- Initialise one combo box field
- */
- static void runlevels_setcombo (
- DIALOG &dia,
- const char *title,
- SSTRING &s,
- int curval,
- const char *values[])
- {
- s.setfrom (values[curval]);
- FIELD_COMBO *comb = dia.newf_combo (title,s);
- for (int i=0; values[i] != NULL; i++){
- comb->addopt (values[i]);
- }
- }
- /*
- Get the index of a value in a table
- */
- static int runlevels_locate (
- const char *values[],
- SSTRING &s,
- int ¬found, // Will be set to id if not found
- // Will be left unchanged if found.
- int id)
- {
- const char *pt = s.get();
- int ret = 0;
- int i;
- for (i=0; values[i] != NULL; i++){
- if (stricmp(values[i],pt)==0){
- ret = i;
- break;
- }
- }
- if (values[i] == NULL) notfound = id;
- return ret;
- }
-
- PUBLIC void RUNLEVELS::define()
- {
- /* #Specification: askrunlevel / runlevel definition
- askrunlevel let the user select one of six operation
- mode. It also let the user redefine (and rename)
- those operation mode. The user can change any of
- the six proposed mode.
-
- The name (title), the runlevel (for /sbin/init)
- and the network mode (for netconf) and the graphic
- mode (nographic, Workstation and X terminal) can
- be selected for each mode.
- */
- DIALOG dia;
- struct TBSTR{
- SSTRING init;
- SSTRING net;
- SSTRING graphic;
- }tbstr[NB_RUNLEVEL];
- static const char *tbinit[] = {
- "1","2","3","4","5","6",
- "A","B","C","D","E","F",
- "Maintenance",
- NULL
- };
- static const char *tbnet[]={
- MSG_U(M_NONET,"No network"),
- MSG_U(M_CLIENT,"Client"),
- MSG_U(M_SERVER,"Server"),
- NULL
- };
- static const char *tbgraphic[]={
- MSG_U(M_TEXTMODE,"Text mode"),
- MSG_U(M_WORKSTATION,"Workstation"),
- MSG_U(M_XTERM,"X terminal"),
- NULL
- };
- RUNLEVEL *ptrun = tbrun;
- TBSTR *ptstr = tbstr;
- for (int i=0; i<NB_RUNLEVEL; i++, ptrun++, ptstr++){
- dia.newf_title ("","");
- dia.newf_str (MSG_U(F_TITLE,"Title"),ptrun->title);
- int init_r = ptrun->init_runlevel;
- if (init_r == 'S'){
- init_r = 12;
- }else if (isdigit(init_r)){
- init_r -= '1';
- }else{
- init_r = (init_r - 'A') + 6;
- }
- runlevels_setcombo (dia,MSG_U(F_RUNLEVEL,"init runlevel")
- ,ptstr->init
- ,init_r
- ,tbinit);
- runlevels_setcombo (dia,MSG_U(F_NETMODE,"Network mode")
- ,ptstr->net
- ,ptrun->netconf_runlevel
- ,tbnet);
- runlevels_setcombo (dia,MSG_U(F_GRMODE,"Graphic mode")
- ,ptstr->graphic
- ,ptrun->graphic_level
- ,tbgraphic);
- }
- int pos = 1;
- while (1){
- if (dia.edit (MSG_U(T_RUNDEF,"Runlevels definition")
- ,MSG_U(I_RUNDEF,"You are allowed to name\n"
- "the different runlevel for this machine\n")
- ,help_define.getpath()
- ,pos) != MENU_ACCEPT){
- dia.restore();
- break;
- }else{
- ptrun = tbrun;
- ptstr = tbstr;
- int notfound = 0;
- for (int j=0; j<NB_RUNLEVEL; j++, ptrun++,ptstr++){
- int notfound_one = 0;
- int init_r = runlevels_locate (tbinit
- ,ptstr->init
- ,notfound_one,2);
- if (init_r == 12){
- init_r = 'S';
- }else if (init_r >= 6){
- init_r += 'A' - 6;
- }else{
- init_r += '1';
- }
- ptrun->init_runlevel = init_r;
- ptrun->netconf_runlevel = runlevels_locate (
- tbnet,ptstr->net,notfound_one,3);
- ptrun->graphic_level = runlevels_locate (
- tbgraphic,ptstr->graphic
- ,notfound_one,4);
- if (notfound_one){
- notfound = 1;
- xconf_error (MSG_U(E_IVLDEF,"Invalid definition"));
- pos = j * 5 + notfound_one;
- break;
- }
- }
- if (!notfound){
- save();
- break;
- }
- }
- }
- }
-
-